﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using TTServer.Messages;
using System.Net.Sockets;
using System.Diagnostics;
using TTServer.Utilities;
using libReadWrite;
using libInterface;
using TTServer.Objects;

namespace TTServer
{
    class FileExplorer
    {
        public static int FILE_EXPLORER_ROOT = 1;
        public static int FILE_EXPLORER_DIRECTORY = 2;
        public static int FILE_EXPLORER_FILE = 3;

        private IClientInfoProvider clientInfoProvider;

        public FileExplorer(IClientInfoProvider thread)
        {
            this.clientInfoProvider = thread;
        }

        public static CFileDetail GetFileDetail(String filePath)
        {
            try
            {
                FileInfo fi = new FileInfo(filePath);

                String name = fi.Name;
                long lenght = fi.Length;
                String directoryFullPath = fi.DirectoryName;
                DateTime ct = fi.CreationTime;
                DateTime lat = fi.LastAccessTime;
                DateTime lwt = fi.LastWriteTime;

                CFileDetail fd = new CFileDetail();
                fd.Name = name;
                fd.Lenght = lenght;
                fd.DirectoryFullPath = directoryFullPath;
                fd.CreationTime = ct.ToString();
                fd.LastAccessTime = lat.ToString();
                fd.LastWriteTime = lwt.ToString();

                return fd;
            }
            catch
            {
                return null;
            }
        }

        private void fileExploreRoots()
        {
            List<CFileInformation> list = this.exploreRoots();

            CFileInformation[] fileInfos = list.ToArray();

            FileExploreResponseMessage msg = new FileExploreResponseMessage(clientInfoProvider.TemporaryKey, "", fileInfos);
             
            clientInfoProvider.AddToMessageQueue(msg);
        }

        private void fileExploreRoots_2()
        {
            List<CFileInformation> list = this.exploreRoots();

            CFileInformation[] fileInfos = list.ToArray();

            PPTOpenFileResponseMessage msg = new PPTOpenFileResponseMessage(clientInfoProvider.TemporaryKey, "", fileInfos);
            
            clientInfoProvider.AddToMessageQueue(msg);
        }

        private void fileExploreRoots_3()
        {
            List<CFileInformation> list = this.exploreRoots();

            CFileInformation[] fileInfos = list.ToArray();

            DSOpenFileResponseMessage msg = new DSOpenFileResponseMessage(clientInfoProvider.TemporaryKey, "", fileInfos);

            clientInfoProvider.AddToMessageQueue(msg);
        }

        private CFileInformation[] fileExploreTheDirectory_sub(string dirPath)
        {
            List<CFileInformation> list1 = this.exploreDirectoryReturnDirList_opt2(dirPath);

            List<CFileInformation> list2 = this.exploreDirectoryReturnFileList(dirPath);

            int n = list1.Count + list2.Count;
            CFileInformation[] l = new CFileInformation[n];

            for (int i = 0; i < n; i++)
            {
                l[i] = new CFileInformation();
            }

            for (int i = 0; i < list1.Count; i++)
            {
                l[i].path = list1[i].path;
                l[i].type = list1[i].type;
            }

            for (int j = 0; j < list2.Count; j++)
            {
                l[j + list1.Count].path = list2[j].path;
                l[j + list1.Count].type = list2[j].type;
            }

            return l;
        }

        private void fileExploreTheDirectory(string dirPath)
        {
            CFileInformation[] l = fileExploreTheDirectory_sub(dirPath);

            FileExploreResponseMessage msg = new FileExploreResponseMessage(clientInfoProvider.TemporaryKey, dirPath, l);
            clientInfoProvider.AddToMessageQueue(msg);

        }

        private void fileExploreTheDirectory_2(string dirPath)
        {
            CFileInformation[] l = fileExploreTheDirectory_sub(dirPath);

            PPTOpenFileResponseMessage msg = new PPTOpenFileResponseMessage(clientInfoProvider.TemporaryKey, dirPath, l);
            clientInfoProvider.AddToMessageQueue(msg);

        }

        private void fileExploreTheDirectory_3(string dirPath)
        {
            CFileInformation[] l = fileExploreTheDirectory_sub(dirPath);

            DSOpenFileResponseMessage msg = new DSOpenFileResponseMessage(clientInfoProvider.TemporaryKey, dirPath, l);
            clientInfoProvider.AddToMessageQueue(msg);
        }


        public void processFileExploreRequestMessage(FileExploreRequestMessage msg)
        {
            if (msg.Directory.Length == 0 && msg.File.Length == 0)
            {
                //Root
                this.fileExploreRoots();
            }
            else if (msg.Directory.Length == 0 && msg.File.Length > 0)
            {
                // File
                // this.fileExplore(new File(action.file));
                //
                // if (Check_The_File_Is_MP3_or_WMA(msg.File))
                // {
                //    Process.Start(msg.File);
                // }
                // else
                // {
                //    NotifyMessage nm1 = new NotifyMessage("File type not supported");
                //    nm1.WriteMessage(clientInfoProvider.getWriter());
                //
                //    NotifyMessage nm2 = new NotifyMessage("Please try mp3, wma files");
                //    nm2.WriteMessage(clientInfoProvider.getWriter());
                // }
            }
            else if (msg.Directory.Length > 0 && msg.File.Length == 0)
            {
                //Drive + Directory
                this.fileExploreTheDirectory(msg.Directory);
            }
        }

        public void processPPTOpenFileRequestMessage(PPTOpenFileRequestMessage msg)
        {
            if (msg.Type == FileExplorer.FILE_EXPLORER_ROOT)
            {
                //Root
                this.fileExploreRoots_2();
            }
            else if (msg.Type == FileExplorer.FILE_EXPLORER_FILE)
            {
                if (Check_The_File_Is_PPT_or_PPTX(msg.Text))
                {
                    //Process.Start(msg.Text);

                    PPTController.Instance.Open(msg.Text);
                }
                else
                {
                    NotifyMessage nm1 = new NotifyMessage("File type not supported");
                    clientInfoProvider.AddToMessageQueue(nm1);

                    NotifyMessage nm2 = new NotifyMessage("Please try ppt, pptx files");
                    clientInfoProvider.AddToMessageQueue(nm2);
                }
            }
            else if (msg.Type == FileExplorer.FILE_EXPLORER_DIRECTORY)
            {
                //Drive + Directory
                this.fileExploreTheDirectory_2(msg.Text);
            }


        }

        public void processDSOpenFileRequestMessage(DSOpenFileRequestMessage msg)
        {
            if (msg.Type == FileExplorer.FILE_EXPLORER_ROOT)
            {
                //Root
                this.fileExploreRoots_3();
            }
            else if (msg.Type == FileExplorer.FILE_EXPLORER_FILE)
            {
                if (Check_The_File_Is_DS(msg.Text))
                {
                    //Process.Start(msg.Text);

                    //PPTController.Instance.Open(msg.Text);

                    
                }
                else
                {
                    NotifyMessage nm1 = new NotifyMessage("File type not supported");
                    clientInfoProvider.AddToMessageQueue(nm1);

                    NotifyMessage nm2 = new NotifyMessage("Please try *.ds files");
                    clientInfoProvider.AddToMessageQueue(nm2);
                }
            }
            else if (msg.Type == FileExplorer.FILE_EXPLORER_DIRECTORY)
            {
                //Drive + Directory
                this.fileExploreTheDirectory_3(msg.Text);
            }
        }

        private bool Check_The_File_Is_MP3_or_WMA(String filePath)
        {
            String path = filePath.ToLower();

            String[] exts = { ".mp3", ".wma" };


            for (int i = 0; i < exts.Length; i++)
            {
                if (filePath.EndsWith(exts[i]) == true)
                {
                    return true;
                }
            }

            return false;
        }

        private bool Check_The_File_Is_PPT_or_PPTX(String filePath)
        {
            String path = filePath.ToLower();

            String[] exts = { ".ppt", ".pptx" };


            for (int i = 0; i < exts.Length; i++)
            {
                if (filePath.EndsWith(exts[i]) == true)
                {
                    return true;
                }
            }

            return false;
        }

        private bool Check_The_File_Is_DS(String filePath)
        {
            String path = filePath.ToLower();

            String[] exts = { ".ds" };


            for (int i = 0; i < exts.Length; i++)
            {
                if (filePath.EndsWith(exts[i]) == true)
                {
                    return true;
                }
            }

            return false;
        }

        /// <summary>
        /// These following functions not depending on m_socket
        /// </summary>

        //<drv.Name>"C:\\"</drv.Name>
        public List<CFileInformation> exploreRoots()
        {
            try
            {
                List<CFileInformation> l = new List<CFileInformation>();

                foreach (DriveInfo drv in DriveInfo.GetDrives())
                {
                    if (drv.IsReady)
                    {
                        CFileInformation temp = new CFileInformation();
                        
                        temp.path = drv.Name;

                        if (drv.DriveType == DriveType.Fixed)
                        {
                            temp.type = CFileInformation.FIXED;
                        }
                        else if (drv.DriveType == DriveType.CDRom)
                        {
                            temp.type = CFileInformation.CDROM;
                        }
                        else if (drv.DriveType == DriveType.Network)
                        {
                            temp.type = CFileInformation.NETWORK_DRIVE;
                        }
                        else if (drv.DriveType == DriveType.NoRootDirectory)
                        {
                            temp.type = CFileInformation.NO_ROOTDIRECTORY;
                        }
                        else if (drv.DriveType == DriveType.Ram)
                        {
                            temp.type = CFileInformation.RAM;
                        }
                        else if (drv.DriveType == DriveType.Removable)
                        {
                            temp.type = CFileInformation.REMOVABLE;
                        }
                        else if (drv.DriveType == DriveType.Unknown)
                        {
                            temp.type = CFileInformation.UNKNOWN;
                        }
                        else {
                            temp.type = CFileInformation.UNKNOWN;
                        }

                        l.Add(temp);
                    }
                }
                return l;
            }
            catch
            {
                return new List<CFileInformation>();
            }
        }

        public List<string> exploreDirectoryReturnDirList(string DirPath)
        {
            try
            {
                List<string> strList = new List<string>();

                DirectoryInfo dr = new DirectoryInfo(DirPath);

                foreach (DirectoryInfo dir in dr.GetDirectories())
                {
                    string temp = dir.Name;
                    strList.Add(temp);
                }

                return strList;
            }
            catch
            {
                return new List<string>();
            }
        }

        //<param>C:\\</param>
        //<item>"C:\\Program Files"</item>

        //<param>"C:\\Program Files"</param>
        //<item>"C:\\Program Files\\Adobe"</item>

        //<param>"C:\\Program Files//"</param>
        //<item>"C:\\Program Files//Adobe"</item>

        //<param>"C:\\Program Files\\"</param>
        //<item>"C:\\Program Files\\Adobe"</item>

        //<param>"C:\\Program Files\\\\"</param>
        //<item>"C:\\Program Files\\\\Adobe"</item>

        public List<CFileInformation> exploreDirectoryReturnDirList_opt2(string DirPath)
        {
            try
            {
                List<CFileInformation> fileInfos = new List<CFileInformation>();

                string path = DirPath;

                string[] Directories = Directory.GetDirectories(path);

                if (Directories.Length == 0)
                {
                    return fileInfos;
                }
                else
                {
                    int len = Directories.Length;
                    for (int i = 0; i < len; i++)
                    {
                        CFileInformation temp = new CFileInformation();
                        temp.path = Directories[i];
                        temp.type = CFileInformation.FOLDER;

                        fileInfos.Add(temp);
                    }
                }
                return fileInfos;
            }
            catch
            {
                //Một khi co loi thi tra ve danh sach rong
                return new List<CFileInformation>();
            }
        }

        public List<CFileInformation> exploreDirectoryReturnFileList(string DirPath)
        {
            try
            {
                List<CFileInformation> fileInfos = new List<CFileInformation>();

                String[] files = Directory.GetFiles(DirPath);

                if (files.Length == 0)
                {
                    return fileInfos;
                }
                else
                {
                    int len = files.Length;
                    for (int i = 0; i < len; i++)
                    {
                        CFileInformation temp = new CFileInformation();
                        temp.path = files[i];
                        temp.type = CFileInformation.FILE;

                        fileInfos.Add(temp);
                    }
                }
                return fileInfos;
            }
            catch
            {
                return new List<CFileInformation>();
            }
        }

        public string GetFileName(string path)
        {
            try
            {
                int Nameindex = path.LastIndexOf('\\');
                return path.Substring(Nameindex + 1);
            }
            catch
            {
                return "N/A";
            }
        }

        public string GetTypeinfo(string path)
        {
            try
            {
                int Typeindex = path.LastIndexOf('.');
                string FType;
                if (Typeindex != -1)
                {
                    FType = path.Substring(Typeindex + 1);
                    FType = FType.ToUpper();
                    if (FType == "AVI" || FType == "3GP" || FType == "WMV")
                    {
                        FType = "Video Clip";
                    }
                    else if (FType == "MP3")
                    {
                        FType = "MP3 Format Sound";
                    }
                    return FType;
                }
                else
                {
                    FType = "FILE";
                    return FType;
                }
            }
            catch
            {
                return "N/A";
            }
        }

        public string GetSizeinfo(string path)
        {
            try
            {
                FileInfo fi = new FileInfo(path);
                long size = fi.Length;
                string txtsize = "";
                if (size < 1024)
                {
                    txtsize = "byte";
                }
                else if (size > 1024)
                {
                    size = size / 1024;
                    txtsize = "Kb";
                }
                if (size > 1024)
                {
                    size = size / 1024;
                    txtsize = "Mb";
                }
                if (size > 1024)
                {
                    size = size / 1024;
                    txtsize = "Gb";
                }
                return size + " " + txtsize;
            }
            catch
            {
                return "N/A";
            }
        }
    }
}
